﻿#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>

//int main()//内存会被分为一个个内存单元，每个内存单元是一个字节，每个内存单元会有一个编号==地址==c语言中被称为指针
//{
//	int a = 25;//变量创建的本质是在内存中开辟一块空间
//	printf("%p", &a);//&--取地址操作符   %p是专门打印地址的（打印的是16进制）
//	return 0;       //虽然有四个字节，但只拿地址较小的那一个,&a取出的是a所占4个字节中地址较⼩的字节的地址。
//}


//int main()
//{
//	int a = 20;
//	//printf("%p\n", &a);
//	int* p = &a;//p是指针变量--存放指针变量（地址）。*说明p是指针变量。int说明p指向的对像是int类型
//
//	return 0;
//}
 
//int main()//解引⽤操作符(*)
//{
//	int a = 20;
//	int* p = &a;
//	*p = 100;//解引用操作（间接访问操作） *p等价于a
//	printf("%d\n", a);
//	return 0;  
//}

//int main()//指针变量的大小
//{
//	//32位平台下地址是32个bit位，指针变量⼤⼩是4个字节
//	//64位平台下地址是64个bit位，指针变量⼤⼩是8个字节
//	//指针变量的⼤⼩和类型是⽆关的，只要指针类型的变量，在相同的平台下，⼤⼩都是相同的。
//	int a = 10;
//	char ch = 'w';
//	int* p = &a;
//	char* pa = &ch;
//	printf("%zd\n", sizeof(p));
//	printf("%zd\n", sizeof(pa));
//	return 0;
//}

//int main()//. 指针变量类型的意义:指针类型决定了指针解应用的时候访问多大的空间
//{        // char* 的指针解引⽤就只能访问⼀个字节，⽽ int* 的指针的解引⽤就能访问四个字节。
//	int a = 0x11223344;
//	//int* p = &a;
//	char* p = &a;
//	*p = 0;
//	return 0;
//}

//int main()//指针+-整数
//{
//	int a = 10;
//	int* p = &a;
//	char* p1 = &a;
//
//	printf("p=%p\n", p);//指针的类型决定了指针向前或者向后⾛⼀步有多⼤（距离）。
//	printf("p+1%p\n", p+1);//type* p-->p+i是跳过i个type类型的数据，跳了i*sizeof(type)个字节
//
//	printf("%p1=p\n", p1);
//	printf("%p1+1=p\n", p1 + 1);
//	return 0;
//}

//int main()//void* 指针
//{
//	int a = 10;
//	/*int* p1;
//	char* p2;
//	double* p3;*/
//	void* p4=&a;//⽆具体类型的指针（或者叫泛型指针），这种类型的指针可以⽤来接受任意类型地址
//	return 0;   //void* 类型的指针不能直接进⾏指针的 + -整数和解引⽤的运算
//}


//int main()//const(常属性)修饰指针变量                                                                       
//{
//	                   //p是指针变量，里面存放了其他变量地址。*p是指针指向的对象n。p也有自己的地址
//	const int n = 10;
//	int m = 100;                  //const修饰指针变量2种情况  1，const放在*左边。2，const放在*右边
//	const int* p = &n;//const放在*左边,限制的是*p。意思是不能通过p改变p指向对象的内容，但p本身可以改变，可以指向其它对象
//	*p = 20;//error
//	p = &m;//ok
//	
//
//	const int n = 10;
//	int* const p = &n;//const放在*右边，限制的是p，不能修改p本身的值，但p指向的内容是可以通过p改变的
//	int m = 100;
//	*p = 20;//ok
//	p = &m;//error
//	return 0;
//}


//int main()//指针运算---指针 +- 整数
//{
//	int arr[10] = { 1,2,3,4,5,6,7,8,9,10 }; 
//	int i = 0;
//	int sz = sizeof(arr) / sizeof(arr[0]);//数组中元素地址是连续的
//	int* p = &arr[0];//p+1
//	for (i = 0; i < sz; i++)
//	{
//		printf("%d ", *p);
//		p++;//p=p+1
//		//printf("%d ",*(p+i));
//	}
//	return 0;
//}


//int my_strlen(char *p)//数组名是数组首元素地址
//{
//	/*int count = 0;
//	while (*p != '\0')
//	{
//		count++;
//		p++;
//	}
//	return count;*/
//	char* p1 = p;
//	while (*p != '\0')
//	{
//		p++;
//	}
//	return p-p1;
//}
//int main()//指针运算---指针-指针（前提是指针指向同一块空间）
//{
//	/*int arr[10] = {0};
//	char ch[] = {};
//	printf("%d\n", &arr[9] - &arr[0]);//指针-指针的绝对值是指针之间的元素个数
//	printf("%d\n", &arr[9] - &ch[0]);//error
//	return 0;*/
//
//	char arr[] = "abcdef";//指针-指针用途
//	int len = my_strlen(arr);
//	printf("%d\n", len);
//	return 0;
//}

//int main()//指针的关系运算--比较大小
//{
//	int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
//	int sz = sizeof(arr) / sizeof(arr[0]);
//	int* p = &arr[0];
//	while (p < arr + sz) //指针的⼤⼩⽐较
//	{
//		printf("%d ", *p);
//		p++;
//	}
//	return 0;
//}

//int main()//野指针:指针指向的位置是不可知的（随机的、不正确的、没有明确限制的）
//{
//	int* p;//局部变量指针未初始化，默认为随机值
//	*p = 20;
//	printf("%d\n", *p);
//	return 0;
//}

//int main()// 指针越界访问
//{
//	int arr[10] = { 0 };
//	int* p = &arr[0];
//	for (int i = 0; i <= 11; i++)
//	{
//		//当指针指向的范围超出数组arr的范围时，p就是野指针
//		*(p++) = i;
//	}
//	return 0;
//}

int* test()//指针指向的空间释放
{
	int n = 100;
	return &n;
}
int main()
{
	int* p = test();
	printf("%d\n", *p);
	return 0;
}